{% extends "admin42/platformmgr/base.html" %}
{% load admin_utils %}
{% block main_content %}
<div id="platform-clusters-list" class="p20">
    <bk-alert type="warning" title="集群信息变更后, 需要重启 bkpaas3-apiserver-web、bkpaas3-apiserver-worker 进程才能生效；若执行集群扩缩容操作，请及时更新对应集群节点状态" class="mb15"></bk-alert>
    <bk-button theme="primary" class="mb20" @click="handleCreate">
        创建集群
    </bk-button>
    <bk-table :data="data" :cell-class-name="cellStyleCallback">
        <bk-table-column type="expand" width="30">
            <template slot-scope="props">
                <bk-table :data="props.row.api_servers" :outer-border="false" :header-cell-style="{background: '#fff', borderRight: 'none'}">
                    <bk-table-column type="index" label="序列" width="60"></bk-table-column>
                    <bk-table-column prop="host" label="主机地址"></bk-table-column>
                    <bk-table-column prop="overridden_hostname" label="DNS覆写域名"></bk-table-column>
                    <bk-table-column label="操作">
                        <template slot-scope="subProps">
                            <bk-button class="ml5" theme="danger" text @click="unbindApiServer(props.row, subProps.row)">删除</bk-button>
                        </template>
                    </bk-table-column>
                    <div slot="append" class="bk-table-append-block" @click="upsertApiServer(props.row)">
                        <div style="display: flex; flex-direction: column;">
                            <i class="bk-icon icon-plus-circle" style="font-size: 16px"></i>
                            <span>添加 APIServer</span>
                        </div>
                    </div>
                </bk-table>
            </template>
        </bk-table-column>
        <bk-table-column label="集群名称" prop="name" width="100"></bk-table-column>
        <bk-table-column label="所属区域" prop="region" width="100"></bk-table-column>
        <bk-table-column label="集群类型" prop="type" width="100">
            <template slot-scope="props">
                <span v-if="props.row.type == 'normal'">普通</span>
                <span v-if="props.row.type == 'virtual'">虚拟</span>
            </template>
        </bk-table-column>
        <bk-table-column label="默认集群" width="100">
            <template slot-scope="props">
                <span v-if="props.row.is_default">✅</span>
                <span v-else>❌</span>
            </template>
        </bk-table-column>
        <bk-table-column label="集群 ID" width="150">
            <template slot-scope="props">
                <span v-if="props.row.annotations.bcs_cluster_id"> $[ props.row.annotations.bcs_cluster_id ] </span>
                <span v-else>--</span>
            </template>
        </bk-table-column>
        <bk-table-column label="集群描述" prop="description"></bk-table-column>
        <bk-table-column label="特性标志" min-width="280">
            <template slot-scope="props">
                <div class="mt15 mb15">
                    <div v-for="ff in featureFlagList" style="display: flex">
                        <bk-tag v-if="hasFeatureFlag(props.row, ff.value)" theme="success">✔ $[ ff.text ]</bk-tag>
                        <bk-tag v-else theme="danger">✘ $[ ff.text ]</bk-tag>
                    </div>
                </div>
            </template>
        </bk-table-column>
        <bk-table-column label="节点" min-width="300">
            <template slot-scope="props">
                <div class="mt15 mb15">
                    <div v-for="(node, idx) in props.row.nodes" style="display: flex">
                        <bk-tag v-show="idx < 5">$[ node ]</bk-tag>
                    </div>
                    <span class="ml10">共计 $[ props.row.nodes.length ] 个节点</span>
                    <bk-button
                        theme="primary" text class="ml10"
                        v-if="props.row.nodes.length > 5"
                        v-bk-tooltips="{content: props.row.nodes.join('<br>'), allowHTML: true}"
                    >查看更多</bk-button>
                </div>
            </template>
        </bk-table-column>
        <bk-table-column label="操作" width="300">
            <template slot-scope="props">
                <bk-button class="ml5" theme="primary" text @click="handleView(props.row)">查看</bk-button>
                <bk-button class="ml5" theme="primary" text @click="handleEdit(props.row)">编辑</bk-button>
                <bk-button
                    class="ml5" theme="primary" text
                    v-bk-tooltips="genTooltipsConfig(props.row)"
                    @click="handleGenNodeState(props.row.region, props.row.name)"
                >同步节点信息</bk-button>
                <bk-button class="ml5" theme="primary" text @click="setAsDefault(props.row)">设为默认集群</bk-button>
            </template>
        </bk-table-column>
    </bk-table>

    <!-- 查看集群详情用弹窗 -->
    <bk-dialog
        v-model="readOnlyDialog.visible"
        header-position="left"
        width="800"
        :mask-close="true"
        :show-footer="false"
    >
        <div slot="header">应用集群详情</div>
        <bk-form :label-width="140" :model="readOnlyDialog.form">
            <bk-form-item label="所属区域">
                <bk-select v-model="readOnlyDialog.form.region" disabled="true">
                    <bk-option
                        v-for="region in regionList"
                        :key="region.value"
                        :id="region.value"
                        :name="region.text">
                    </bk-option>
                </bk-select>
            </bk-form-item>
            <bk-form-item label="集群名称">
                <bk-input v-model="readOnlyDialog.form.name" disabled="true"></bk-input>
            </bk-form-item>
            <bk-form-item label="集群类型">
                <bk-select v-model="readOnlyDialog.form.type" disabled="true">
                    <bk-option
                        v-for="type in clusterTypeList"
                        :key="type.value"
                        :id="type.value"
                        :name="type.text">
                    </bk-option>
                </bk-select>
            </bk-form-item>
            <bk-form-item label="默认集群">
                <bk-switcher v-model="readOnlyDialog.form.is_default" disabled="true"></bk-switcher>
            </bk-form-item>
            <bk-form-item label="集群描述">
                <bk-input v-model="readOnlyDialog.form.description" disabled="true"></bk-input>
            </bk-form-item>
            <bk-form-item label="子路径根域名">
                <json-pretty
                    :data="readOnlyDialog.form.ingress_config.sub_path_domains"
                    show-length highlight-mouseover-node :deep="2"
                ></json-pretty>
            </bk-form-item>
            <bk-form-item label="子域名根域名">
                <json-pretty
                    :data="readOnlyDialog.form.ingress_config.app_root_domains"
                    show-length highlight-mouseover-node :deep="2"
                ></json-pretty>
            </bk-form-item>
            <bk-form-item label="集群出口 IP" desc="用于指引用户配置独立域名的解析, 如果集群使用云厂商的 clb 做流量控制, 那么这里应当填对应的 vip">
                <bk-input v-model="readOnlyDialog.form.ingress_config.frontend_ingress_ip" disabled="true"></bk-input>
            </bk-form-item>
            <bk-form-item label="注解" required>
                <json-pretty
                    :data="readOnlyDialog.form.annotations"
                    show-length highlight-mouseover-node :deep="2"
                ></json-pretty>
            </bk-form-item>
            <bk-form-item label="特性标志">
                <div v-for="ff in featureFlagList" style="display: flex">
                    <bk-tag v-if="hasFeatureFlag(readOnlyDialog.form, ff.value)" theme="success">✔ $[ ff.text ]</bk-tag>
                    <bk-tag v-else theme="danger">✘ $[ ff.text ]</bk-tag>
                </div>
            </bk-form-item>
            <bk-form-item label="数字证书认证机构（cert-authority）">
                <bk-input
                    v-if="readOnlyDialog.form.ca_data"
                    type="textarea"
                    rows="5"
                    v-model="readOnlyDialog.form.ca_data"
                    disabled="true"
                ></bk-input>
                <span v-else>--</span>
            </bk-form-item>
            <bk-form-item label="客户端证书（client-cert）">
                <bk-input
                    v-if="readOnlyDialog.form.cert_data"
                    type="textarea"
                    rows="5"
                    v-model="readOnlyDialog.form.cert_data"
                    disabled="true"
                >
                </bk-input>
                <span v-else>--</span>
            </bk-form-item>
            <bk-form-item label="客户端密钥（client-key）">
                <bk-input
                    v-if="readOnlyDialog.form.key_data"
                    type="textarea"
                    rows="5"
                    v-model="readOnlyDialog.form.key_data"
                    disabled="true"
                >
                </bk-input>
                <span v-else>--</span>
            </bk-form-item>
            <bk-form-item label="集群 Token" :required="false">
                <bk-input
                    v-if="readOnlyDialog.form.token_value"
                    type="textarea"
                    rows="5"
                    v-model="readOnlyDialog.form.token_value"
                    disabled="true"
                >
                </bk-input>
                <span v-else>--</span>
            </bk-form-item>
            <bk-form-item label="端口配置">
                <bk-alert type="info" title="用于生成应用访问地址"></bk-alert>
                <bk-input
                    placeholder="使用 http 协议访问 SaaS 时, 使用的端口号"
                    type="number"
                    v-model="readOnlyDialog.form.ingress_config.port_map.http"
                >
                    <template slot="prepend">
                        <div class="group-text">HTTP</div>
                    </template>
                </bk-input>
                <bk-input
                    placeholder="使用 https 协议访问 SaaS 时, 使用的端口号"
                    type="number"
                    v-model="readOnlyDialog.form.ingress_config.port_map.https"
                >
                    <template slot="prepend">
                        <div class="group-text">HTTPS</div>
                    </template>
                </bk-input>
            </bk-form-item>
            <bk-form-item label="默认 nodeSelector" desc="限制应用的构建、运行均使用此 nodeSelector 来筛选节点">
                <json-pretty
                    :data="readOnlyDialog.form.default_node_selector"
                    show-length highlight-mouseover-node :deep="0"
                ></json-pretty>
            </bk-form-item>
            <bk-form-item label="默认 tolerations" desc="让应用的构建、运行使用此 tolerations 来容忍节点的污点（taints）">
                <json-pretty
                    :data="readOnlyDialog.form.default_tolerations"
                    show-length highlight-mouseover-node :deep="0"
                ></json-pretty>
            </bk-form-item>
            <bk-form-item label="默认 Ingress 域名模板（保留选项）">
                <bk-input v-model="readOnlyDialog.form.ingress_config.default_ingress_domain_tmpl" disabled="true"></bk-input>
            </bk-form-item>
        </bk-form>
    </bk-dialog>

    <!-- 编辑 / 创建集群用弹窗   -->
    <bk-dialog
        v-model="dialog.visible"
        header-position="left"
        width="800"
        :confirm-fn="submitDialog"
        @cancel="cancelDialog"
        :mask-close="false"
    >
        <div slot="header">
            $[ dialog.type === 'create'?'添加':'编辑' ]应用集群
        </div>
        <bk-form :label-width="140" :model="dialog.form">
            <bk-form-item label="所属区域" :required="true" :desc="dialog.type !== 'create'?'集群创建后不可变更':''">
                <bk-select v-model="dialog.form.region" :disabled="dialog.type !== 'create'">
                    <bk-option
                        v-for="region in regionList"
                        :key="region.value"
                        :id="region.value"
                        :name="region.text">
                    </bk-option>
                </bk-select>
            </bk-form-item>
            <bk-form-item label="集群名称" required :desc="dialog.type !== 'create'?'集群创建后不可变更':''">
                <bk-input v-model="dialog.form.name" :disabled="dialog.type !== 'create'"></bk-input>
            </bk-form-item>
            <bk-form-item label="集群类型" required :desc="dialog.type !== 'create'?'集群创建后不可变更':''">
                <bk-select v-model="dialog.form.type" :disabled="dialog.type !== 'create'">
                    <bk-option
                        v-for="type in clusterTypeList"
                        :key="type.value"
                        :id="type.value"
                        :name="type.text">
                    </bk-option>
                </bk-select>
            </bk-form-item>
            <bk-form-item label="默认集群" required :desc="dialog.type !== 'create'?'不支持通过编辑切换默认集群':''">
                <bk-switcher v-model="dialog.form.is_default" :disabled="dialog.type !== 'create'"></bk-switcher>
            </bk-form-item>
            <bk-form-item label="集群描述" required>
                <bk-input v-model="dialog.form.description"></bk-input>
            </bk-form-item>
            <bk-form-item label="子路径根域名" desc="在拼接应用子路径访问地址时遵循以下规则: 'http(s)://{子路径根域名}/{应用子路径}/'">
                <json-editor ref='subPathDomainsEditor' v-model="dialog.form.ingress_config.sub_path_domains" :schema="DomainSchema"></json-editor>
                <bk-alert type="info" title="支持填写多个域名，每个域名必须有 3 个属性: 域名(name,str)、开启HTTPS(https_enabled,bool)、保留域名(即不推荐再使用的域名,reserved,bool)。
                  如：[{&quot;name&quot;: &quot;example.com&quot;, &quot;https_enabled&quot;: false, &quot;reserved&quot;: false}]">
                </bk-alert>
            </bk-form-item>
            <bk-form-item label="子域名根域名" desc="在拼接应用子域名访问地址时遵循以下规则: 'http(s)://{应用子域名}.{子域名根域名}/', 如果不配置该值, 默认与 子路径根域名 一致">
                <json-editor v-model="dialog.form.ingress_config.app_root_domains" :schema="DomainSchema"></json-editor>
                <bk-alert type="info" title="支持填写多个域名，每个域名必须有 3 个属性: 域名(name,str)、开启HTTPS(https_enabled,bool)、保留域名(即不推荐再使用的域名,reserved,bool)。
                  如：[{&quot;name&quot;: &quot;example.com&quot;, &quot;https_enabled&quot;: false, &quot;reserved&quot;: false}]">
                </bk-alert>
            </bk-form-item>
            <bk-form-item label="集群出口 IP" required desc="用于指引用户配置独立域名的解析, 如果集群使用云厂商的 clb 做流量控制, 那么这里应当填对应的 vip">
                <bk-input v-model="dialog.form.ingress_config.frontend_ingress_ip"></bk-input>
            </bk-form-item>
            <bk-form-item label="注解" required>
                <json-editor v-model="dialog.form.annotations"></json-editor>
            </bk-form-item>
            <bk-form-item label="特性标志" desc="不同的集群可能拥有不同的特性，请根据实际需要编辑">
                <bk-select
                    multiple
                    v-model="dialog.form.enabled_feature_flags"
                    display-tag
                    @change="updateFeatureFlags"
                >
                    <bk-option
                        v-for="type in featureFlagList"
                        :key="type.value"
                        :id="type.value"
                        :name="type.text">
                    </bk-option>
                </bk-select>
            </bk-form-item>
            <bk-form-item label="数字证书认证机构（cert-authority）">
                <bk-input
                    placeholder="请输入 Base64 编码后的证书"
                    type="textarea"
                    rows="5"
                    v-model="dialog.form.ca_data"
                >
                </bk-input>
            </bk-form-item>
            <div class="m15">客户端证书秘钥与集群 Token 选择一项填写即可</div>
            <bk-form-item label="客户端证书（client-cert）">
                <bk-input
                    placeholder="请输入 Base64 编码后的证书"
                    type="textarea"
                    rows="5"
                    v-model="dialog.form.cert_data"
                >
                </bk-input>
            </bk-form-item>
            <bk-form-item label="客户端密钥（client-key）">
                <bk-input
                    placeholder="请输入 Base64 编码后的证书"
                    type="textarea"
                    rows="5"
                    v-model="dialog.form.key_data"
                >
                </bk-input>
            </bk-form-item>
            <bk-form-item label="集群 Token" :required="false">
                <bk-input
                    placeholder="请输入可通过集群校验的 Token"
                    type="textarea"
                    rows="5"
                    v-model="dialog.form.token_value"
                >
                </bk-input>
            </bk-form-item>
            <bk-form-item label="端口配置">
                <bk-alert type="info" title="用于生成应用访问地址，当应用网关（BkIngressController）通过非标准端口号暴露时，修改本设置。"></bk-alert>
                <bk-input
                    placeholder="使用 http 协议访问 SaaS 时, 使用的端口号"
                    type="number"
                    v-model="dialog.form.ingress_config.port_map.http"
                >
                    <template slot="prepend">
                        <div class="group-text">HTTP</div>
                    </template>
                </bk-input>
                <bk-input
                    placeholder="使用 https 协议访问 SaaS 时, 使用的端口号"
                    type="number"
                    v-model="dialog.form.ingress_config.port_map.https"
                >
                    <template slot="prepend">
                        <div class="group-text">HTTPS</div>
                    </template>
                </bk-input>
            </bk-form-item>
            <div class="m15">以下参数为集群与应用相关的默认参数，可控制应用调度策略等。修改这些值后，需重新部署应用方能生效。</div>
            <bk-form-item label="默认 nodeSelector" :required="false">
                <json-editor v-model="dialog.form.default_node_selector" nullable></json-editor>
                <bk-alert type="info" title="限制应用的构建、运行均使用此 nodeSelector 来筛选节点。
                  格式：包含键值对的 JSON 对象，如：{&quot;key&quot;: &quot;value&quot;}"></bk-alert>
            </bk-form-item>
            <bk-form-item label="默认 tolerations" :required="false">
                <json-editor v-model="dialog.form.default_tolerations" nullable></json-editor>
                <bk-alert type="info" title="让应用的构建、运行使用此 tolerations 来容忍节点的“污点（taints）”。
                  格式：元素为 toleration 对象的 JSON 列表，如：[{&quot;key&quot;: &quot;app&quot;, &quot;operator&quot;: &quot;Equal&quot;, &quot;value&quot;: &quot;value1&quot;, &quot;effect&quot;: &quot;NoSchedule&quot;}]"></bk-alert>
            </bk-form-item>
            <bk-form-item label="默认 Ingress 域名模板（保留选项）" desc="保留高级选项，默认留空即可">
                <bk-input
                    placeholder="保留高级选项，默认留空即可"
                    v-model="dialog.form.ingress_config.default_ingress_domain_tmpl"
                ></bk-input>
            </bk-form-item>
        </bk-form>
    </bk-dialog>

    <bk-dialog
        v-model="subDialog.visible"
        width="800"
        theme="primary"
        :mask-close="false"
        @confirm="submitSubDialog"
        :title="subDialog.title"
    >
        <bk-form>
            <bk-form-item label="主机地址" required>
                <bk-input type="url" placeholder="主机地址, 形如 scheme://host:port, 例如 https://127.0.0.1:6443" v-model="subDialog.form.host"></bk-input>
            </bk-form-item>
            <bk-form-item label="DNS覆写域名">
                <bk-input placeholder="DNS覆写域名, 不需要则留空" v-model="subDialog.form.overridden_hostname"></bk-input>
            </bk-form-item>
        </bk-form>
    </bk-dialog>
</div>

{% endblock %}


{% block main_script %}
<script>
    /* beautify preserve:start */
    const regionList = {{ region_list | to_json }}
    const clusterTypeList = {{ cluster_type_list | to_json }}
    const featureFlagList = {{ feature_flag_list | to_json }}
    /* beautify preserve:end */
    const DomainSchema = {
        type: "array",
        items: {
            type: "object",
            properties: {
                name: { type: "string"},
                reserved: { type: "boolean"},
                https_enabled: { type: "boolean"}
            },
            required: ["name", "reserved", "https_enabled"],
        },
        uniqueItems: true
    }

    const URLRouter = {
        create: decodeURI("{% url 'wl_api.clusters' %}"),
        list: decodeURI("{% url 'wl_api.clusters' %}"),
        detail: decodeURI("{% url 'wl_api.cluster_by_id' '${cluster_id}' %}"),
        setAsDefault: decodeURI("{% url 'wl_api.cluster.set_default' '${cluster_id}' %}"),
        genNodeState: decodeURI("{% url 'wl_api.cluster.node_state' '${cluster_name}' %}"),
        apiServer: {
            upsert: decodeURI("{% url 'wl_api.cluster.api_servers' '${cluster_id}' %}"),
            delete: decodeURI("{% url 'wl_api.cluster.api_server_by_id' '${cluster_id}' '${api_server_id}' %}"),
        }
    }

    document.addEventListener('DOMContentLoaded', () => {
        new Vue({
            el: "#platform-clusters-list",
            delimiters: ['$[', ']'],
            mixins: [SubmitMixin],
            data: function() {
                return {
                    data: [],
                    dialog: {
                        visible: false,
                        form: {
                            uuid: '',
                            region: '',
                            name: '',
                            type: '',
                            is_default: false,
                            description: '',
                            ingress_config: {
                                port_map: {},
                                sub_path_domains: [],
                                app_root_domains: [],
                                default_ingress_domain_tmpl: ''
                            },
                            annotations: {},
                            // 全量 feature_flags 信息
                            feature_flags: {},
                            // 已经启用的 feature_flags
                            enabled_feature_flags: [],
                            ca_data: undefined,
                            cert_data: undefined,
                            key_data: undefined,
                            token_value: undefined,
                            default_node_selector: {},
                            default_tolerations: [],
                        },
                        row: undefined
                    },
                    readOnlyDialog: {
                        visible: false,
                        form: {
                            ingress_config: {
                                port_map: {},
                                sub_path_domains: [],
                                app_root_domains: [],
                                default_ingress_domain_tmpl: ''
                            },
                            annotations: {},
                            feature_flags: {},
                            default_node_selector: {},
                            default_tolerations: []
                        },
                        row: undefined
                    },
                    subDialog: {
                        visible: false,
                        title: '',
                        parent: {
                            name: '',
                            uuid: '',
                        },
                        form: {
                            cluster_id: '',
                            host: '',
                            overridden_hostname: '',
                            uuid: ''
                        }
                    },
                    advancedFilterShow: false
                }
            },
            mounted: function () {
                this.fetchClusterList()
            },
            methods: {
                fillUrlTemplate: function(url_template, { row }) {
                    if (!row)
                        row = {}
                    return url_template.replace("${cluster_id}", row.uuid)
                },
                cancelDialog: function() {

                },
                processData: function(data) {
                    return new Promise(resolve => {
                        resolve(data)
                    })
                },
                fetchClusterList: async function () {
                    const el = this.$bkLoading({title: '加载中'})
                    try {
                        await this.$http.get(URLRouter['list']).then(res => {
                            this.data = res
                        })
                    } finally {
                        el.hide = true
                    }
                },
                submitCallback: function() {
                    this.fetchClusterList()
                },
                handleCreate: function() {
                    this.dialog.type = "create"
                    this.dialog.row = undefined

                    this.dialog.form.uuid = undefined
                    this.dialog.form.region = regionList[0].value
                    this.dialog.form.name = undefined
                    this.dialog.form.type = clusterTypeList[0].value
                    this.dialog.form.is_default = false
                    this.dialog.form.description = undefined
                    this.dialog.form.ingress_config = {port_map: {}, sub_path_domains: [], app_root_domains: []}
                    this.dialog.form.annotations = {}
                    this.dialog.form.feature_flags = {}
                    this.dialog.form.enabled_feature_flags = []
                    // 默认集群拥有全量的 featureflag 功能
                    for (var i = 0; i < featureFlagList.length; i++) {
                        ff = featureFlagList[i].value
                        this.dialog.form.feature_flags[ff] = true
                        this.dialog.form.enabled_feature_flags.push(ff)
                    }
                    this.dialog.form.ca_data = undefined
                    this.dialog.form.cert_data = undefined
                    this.dialog.form.key_data = undefined
                    this.dialog.form.token_value = undefined
                    this.dialog.form.default_node_selector = {}
                    this.dialog.form.default_tolerations = []
                    this.dialog.visible = true
                },
                handleEdit: function(row) {
                    this.dialog.type = "edit"
                    this.dialog.row = row

                    // 将 dict 转换成 bk-select 需要的 list
                    var enabled_feature_flags = [];
                    for (var ff in row.feature_flags) {
                      if (row.feature_flags[ff] === true) {
                        enabled_feature_flags.push(ff);
                      }
                    }

                    this.dialog.form = { ...row, ingress_config: {...row.ingress_config}, enabled_feature_flags: enabled_feature_flags }
                    this.dialog.visible = true
                },
                handleView: function(row) {
                    this.readOnlyDialog.row = row
                    this.readOnlyDialog.form = { ...row, ingress_config: {...row.ingress_config} }
                    this.readOnlyDialog.visible = true
                },
                handleGenNodeState: function (region, clusterName) {
                    let url = URLRouter.genNodeState.replace('${cluster_name}', clusterName)
                    this.$http.post(url, {region: region}).then(resp => {
                        this.$bkMessage({theme: 'success', message: `更新集群 [ ${region} / ${clusterName} ] 节点成功`})
                        this.fetchClusterList()
                    })
                },
                setAsDefault: function (row) {
                    let url = URLRouter.setAsDefault.replace("${cluster_id}", row.uuid);
                    this.$http.post(url).then(resp => {
                        this.$bkMessage({theme: 'success', message: `成功设置集群 [ ${row.name} ] 为默认集群`})
                        this.fetchClusterList()
                    })
                },
                // 在多选框被修改时，根据选中的项目，同步更新 feature_flags 内容
                updateFeatureFlags: function () {
                    for (var i = 0; i < featureFlagList.length; i++) {
                      var ff = featureFlagList[i].value;
                      this.dialog.form.feature_flags[ff] = this.dialog.form.enabled_feature_flags.indexOf(ff) >= 0;
                    }
                },
                // 判断当前集群是否支持某特性
                hasFeatureFlag: function (row, ff) {
                    return row.feature_flags[ff]
                },
                cellStyleCallback: function({ row, column, rowIndex, columnIndex }) {
                    if (column.label === "接入层配置" || column.label === '注解')
                        return 'json-view'
                },
                // 子表单
                submitSubDialog: function() {
                    let url_template = this.subDialog.type === "upsert" ? URLRouter['apiServer']['upsert'] : URLRouter['apiServer']['delete']
                    let form = this.subDialog.form
                    let url = url_template.replace("${cluster_id}", this.subDialog.parent.uuid)
                    let method = this.$http.get
                    switch (this.subDialog.type) {
                        case "upsert":
                            method = this.$http.post
                            break
                        case "delete":
                            method = this.$http.delete
                            url = url.replace("${api_server_id}", form.uuid)
                            break
                    }

                    const el = this.$bkLoading({
                        title: '处理中'
                    })
                    method(url, form).then(res => {
                        this.$paasMessage({
                            message: '处理完毕'
                        })
                        this.submitCallback()
                    }, res => {
                        if (res.response.status === 400) {
                            this.$paasMessage({
                                theme: 'error',
                                message: res.detail
                            })
                        } else if (res.response.status === 404) {
                            this.$paasMessage({
                                theme: 'error',
                                message: '资源不存在或登录态已失效'
                            })
                        } else {
                            this.$paasMessage({
                                theme: 'error',
                                message: `程序异常, 状态码: ${res.response.status}`
                            })
                            console.error(res)
                        }
                    }).finally(() => {el.hide = true})
                },
                upsertApiServer: function(cluster, api_server) {
                    let isUpdate = api_server !== undefined ? true : false
                    this.subDialog.title = isUpdate ? `变更 ${cluster.name} 集群的 APIServer` : `为 ${cluster.name} 集群添加 APIServer`
                    this.subDialog.parent = cluster
                    this.subDialog.type = 'upsert'
                    this.subDialog.form = {
                        cluster_id: cluster.uuid,
                        host: isUpdate ? api_server.host : '',
                        overridden_hostname: isUpdate ? api_server.overridden_hostname : '',
                        uuid: isUpdate ? api_server.uuid : '',
                    }
                    this.subDialog.visible = true
                },
                unbindApiServer: function(cluster, api_server) {
                    this.subDialog.title = `移除 ${cluster.name} 集群中的 APIServer`
                    this.subDialog.parent = cluster
                    this.subDialog.type = 'delete'
                    this.subDialog.form = {
                        cluster_id: cluster.uuid,
                        host: api_server.host,
                        overridden_hostname: api_server.overridden_hostname,
                        uuid: api_server.uuid,
                    }
                    this.subDialog.visible = true
                },
                genTooltipsConfig: function (row) {
                    return {
                        content: '为应用集群同步节点的信息，影响 ”模块管理 -> 出口 IP 管理“ 中的 IP 列表，更新后新的节点才会出现在 IP 列表中。<br>' +
                            '该操作等效于: python manage.py region_gen_state --region ' + row.region + ' --cluster-name ' + row.name,
                        allowHTML: true
                    }
                },
                handleRequestError: function (res) {
                    console.error(res)
                }
            },
        })
    })
</script>

<style>
    .bk-table-append-block {
        text-align: center;
        padding: 10px 0;
        margin-bottom: 10px;
    }
    .bk-table-append-block:hover {
        cursor: pointer;
        background-color: #f0f1f5;
    }
</style>
{% endblock %}
